"""
Configuration management for semantic-rag package.
Handles environment variables and provider configuration.
"""

import os
from dataclasses import dataclass
from typing import Optional, Dict, Any, Literal
from pathlib import Path

try:
    from dotenv import load_dotenv
    load_dotenv()
except ImportError:
    # python-dotenv not installed, skip loading .env file
    pass

EmbedderProvider = Literal["openai", "ollama", "openai-compatible", "gemini", "mistral"]


@dataclass
class EmbedderConfig:
    """Configuration for embedder providers."""
    provider: EmbedderProvider
    options: Dict[str, Any]


@dataclass 
class VectorStoreConfig:
    """Configuration for vector store."""
    url: str
    api_key: Optional[str] = None


@dataclass
class SemanticRagConfig:
    """Main configuration class for semantic RAG."""
    # Embedder settings
    embedder_provider: EmbedderProvider = "openai"
    
    # OpenAI Configuration
    openai_api_key: Optional[str] = None
    openai_model_id: str = "text-embedding-3-small"
    
    # Ollama Configuration  
    ollama_base_url: str = "http://localhost:11434"
    ollama_model_id: str = "bge-m3:latest"
    
    # OpenAI Compatible Configuration
    openai_compatible_base_url: Optional[str] = None
    openai_compatible_api_key: Optional[str] = None
    openai_compatible_model_id: str = "text-embedding-ada-002"
    
    # Gemini Configuration
    gemini_api_key: Optional[str] = None
    gemini_model_id: str = "models/text-embedding-004"
    
    # Mistral Configuration
    mistral_api_key: Optional[str] = None
    mistral_model_id: str = "mistral-embed"
    
    # Vector Database Configuration
    qdrant_url: str = "http://localhost:6333"
    qdrant_api_key: Optional[str] = None
    
    # Search Configuration
    default_search_min_score: float = 0.7
    default_max_search_results: int = 20
    
    # Vector Configuration
    vector_dimension: int = 4096
    
    @classmethod
    def from_env(cls) -> 'SemanticRagConfig':
        """Create configuration from environment variables."""
        return cls(
            embedder_provider=os.getenv("EMBEDDER_PROVIDER", "openai"),
            
            # OpenAI
            openai_api_key=os.getenv("OPENAI_API_KEY"),
            openai_model_id=os.getenv("OPENAI_MODEL_ID", "text-embedding-3-small"),
            
            # Ollama
            ollama_base_url=os.getenv("OLLAMA_BASE_URL", "http://localhost:11434"),
            ollama_model_id=os.getenv("OLLAMA_MODEL_ID", "bge-m3:latest"),
            
            # OpenAI Compatible
            openai_compatible_base_url=os.getenv("OPENAI_COMPATIBLE_BASE_URL"),
            openai_compatible_api_key=os.getenv("OPENAI_COMPATIBLE_API_KEY"),
            openai_compatible_model_id=os.getenv("OPENAI_COMPATIBLE_MODEL_ID", "text-embedding-ada-002"),
            
            # Gemini
            gemini_api_key=os.getenv("GEMINI_API_KEY"),
            gemini_model_id=os.getenv("GEMINI_MODEL_ID", "models/text-embedding-004"),
            
            # Mistral
            mistral_api_key=os.getenv("MISTRAL_API_KEY"),
            mistral_model_id=os.getenv("MISTRAL_MODEL_ID", "mistral-embed"),
            
            # Vector Database
            qdrant_url=os.getenv("QDRANT_URL", "http://localhost:6333"),
            qdrant_api_key=os.getenv("QDRANT_API_KEY"),
            
            # Search settings
            default_search_min_score=float(os.getenv("DEFAULT_SEARCH_MIN_SCORE", "0.7")),
            default_max_search_results=int(os.getenv("DEFAULT_MAX_SEARCH_RESULTS", "20")),
            
            # Vector settings
            vector_dimension=int(os.getenv("VECTOR_DIMENSION", "4096")),
        )
    
    def get_embedder_config(self) -> EmbedderConfig:
        """Get embedder configuration based on provider."""
        if self.embedder_provider == "openai":
            return EmbedderConfig(
                provider="openai",
                options={
                    "api_key": self.openai_api_key,
                    "model_id": self.openai_model_id,
                }
            )
        elif self.embedder_provider == "ollama":
            return EmbedderConfig(
                provider="ollama",
                options={
                    "base_url": self.ollama_base_url,
                    "model_id": self.ollama_model_id,
                }
            )
        elif self.embedder_provider == "openai-compatible":
            return EmbedderConfig(
                provider="openai-compatible",
                options={
                    "base_url": self.openai_compatible_base_url,
                    "api_key": self.openai_compatible_api_key,
                    "model_id": self.openai_compatible_model_id,
                }
            )
        elif self.embedder_provider == "gemini":
            return EmbedderConfig(
                provider="gemini",
                options={
                    "api_key": self.gemini_api_key,
                    "model_id": self.gemini_model_id,
                }
            )
        elif self.embedder_provider == "mistral":
            return EmbedderConfig(
                provider="mistral",
                options={
                    "api_key": self.mistral_api_key,
                    "model_id": self.mistral_model_id,
                }
            )
        else:
            raise ValueError(f"Unsupported embedder provider: {self.embedder_provider}")
    
    def get_vector_store_config(self) -> VectorStoreConfig:
        """Get vector store configuration."""
        return VectorStoreConfig(
            url=self.qdrant_url,
            api_key=self.qdrant_api_key,
        )
    
    def validate_embedder_config(self) -> tuple[bool, Optional[str]]:
        """Validate embedder configuration."""
        if self.embedder_provider == "openai":
            if not self.openai_api_key:
                return False, "OPENAI_API_KEY is required when using OpenAI embedder"
        elif self.embedder_provider == "ollama":
            if not self.ollama_base_url:
                return False, "OLLAMA_BASE_URL is required when using Ollama embedder"
        elif self.embedder_provider == "openai-compatible":
            if not self.openai_compatible_base_url or not self.openai_compatible_api_key:
                return False, "OPENAI_COMPATIBLE_BASE_URL and OPENAI_COMPATIBLE_API_KEY are required"
        elif self.embedder_provider == "gemini":
            if not self.gemini_api_key:
                return False, "GEMINI_API_KEY is required when using Gemini embedder"
        elif self.embedder_provider == "mistral":
            if not self.mistral_api_key:
                return False, "MISTRAL_API_KEY is required when using Mistral embedder"
        
        return True, None


# Global configuration instance
_config: Optional[SemanticRagConfig] = None


def get_config() -> SemanticRagConfig:
    """Get global configuration instance."""
    global _config
    if _config is None:
        _config = SemanticRagConfig.from_env()
    return _config


def set_config(config: SemanticRagConfig) -> None:
    """Set global configuration instance."""
    global _config
    _config = config